﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PageRankPlay
{
    public class PageRanker
    {
        private Dictionary<int, HashSet<int>> links = new Dictionary<int,HashSet<int>>();
        private Dictionary<int, HashSet<int>> innerLinks;
        private static readonly double C = 0.95;

        private Dictionary<int, double> ranks;
        public Dictionary<int, double> Ranks {
            get {
                if (ranks == null) ranks = doRanking();
                return ranks;
            }
        }
        public int NodeCount {
            get {
                return links.Count();
            }
        }
        public int InnerNodeCount {
            get {
                return innerLinks.Count();
            }
        }


        private Dictionary<int, double> doRanking() {
            Dictionary<int, double> ranks = innerLinks.ToDictionary(e=>e.Key, e => (double) e.Value.Count());
            double sum = ranks.Values.Sum();
            foreach (int i in ranks.Keys) ranks[i] /= sum; //normalize first strength
            Dictionary<int, double> ranksprime = ranks.ToDictionary(e => e.Key, e=> 0.0);
/*
            foreach (int node in ranks.Keys) {
                double 
                ranksprime[node] = C * 
            }
            */



            throw new NotImplementedException();
        }

        public PageRanker(Dictionary<int, HashSet<int>> linkStructure) {
            links = linkStructure;
            innerLinks = removeDanglers(links);
        }

         private static Dictionary<int, HashSet<int>> removeDanglers(Dictionary<int, HashSet<int>> links) {
             int danglersRemoved;
             Dictionary<int, HashSet<int>> innerLinks = links.ToDictionary(e=>e.Key, e=>e.Value);
             do {
                 danglersRemoved = 0;
                 List<int> danglers = new List<int>();
                 foreach (int node in innerLinks.Keys) {
                     if (innerLinks[node].Count == 0) {
                         danglers.Add(node);
                         danglersRemoved++;
                     }
                 }
                 foreach (int dangler in danglers) {
                     innerLinks.Remove(dangler);
                 }
                 foreach (HashSet<int> outs in innerLinks.Values) {
                     outs.RemoveWhere(e => danglers.Contains(e));
                 }

                 Console.WriteLine("removed {0} danglers", danglersRemoved);
             } while (danglersRemoved > 0);
             return innerLinks;
        }



        static void Main(string[] args) {
            /* hypothetical graph structure:
             * 1->2,3
             * 2->1,4
             * 3->4
             * 4->5,1
             * */
            Dictionary<int, HashSet<int>> testCase = new Dictionary<int, HashSet<int>>();
            for (int i = 1; i < 6; i++) {
                testCase.Add(i, new HashSet<int>());
            }
            testCase[1].Add(2);
            testCase[1].Add(3);
            testCase[2].Add(1);
            testCase[2].Add(4);
            testCase[3].Add(4);
            testCase[4].Add(5);
          //  testCase[4].Add(1);

            PageRanker newRanker = new PageRanker(testCase);
            
            
            Console.WriteLine("Great success!");
            Console.WriteLine("Out of {0} nodes, {1} were central!", newRanker.NodeCount, newRanker.InnerNodeCount);
        }
    }
}
